package com.link_with_health.common;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.SimpleDateFormat;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

public class CacheMap {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    // 缓存实例对象
    private volatile static CacheMap cacheMapObj = new CacheMap();
    private static final Map<String, CacheEntry<String, Object>> cacheMap = new ConcurrentHashMap<String, CacheEntry<String, Object>>();// 缓存容器
    private static final long CLEAR_TIMEOUT = 1000 * 60 * 30;
    private static final long CHECK_TIMEOUT = 1000 * 60 * 10;

    private CacheMap() {
        new ClearThread().start();
    }

    /**
     * 采用单例模式获取缓存对象实例
     */
    public static synchronized CacheMap getInstance() {
        return cacheMapObj;
    }


    private class CacheEntry<K, V> implements Entry<K, V> {
        long time;
        V value;
        K key;

        CacheEntry(K key, V value) {
            super();
            this.value = value;
            this.key = key;
            this.time = System.currentTimeMillis();
        }

        @Override
        public K getKey() {
            return key;
        }

        @Override
        public V getValue() {
            return value;
        }

        @Override
        public V setValue(V value) {
            return this.value = value;
        }
    }

    private class ClearThread extends Thread {
        ClearThread() {
            setName("clear cache thread");
        }

        public void run() {
            while (true) {
                long now = System.currentTimeMillis();
                SimpleDateFormat sdf =  new SimpleDateFormat(  "yyyy-MM-dd HH:mm:ss" );
                logger.info("[定时检查: " + sdf.format(now) + " >> " + cacheMap.size()+"]");
                Set<String> keys = cacheMap.keySet();
                for (String key : keys) {
                    CacheEntry<String, Object> entry = cacheMap.get(key);
                    if (now - entry.time >= CLEAR_TIMEOUT) {
                        synchronized (cacheMap) {
                            logger.info("[删除过期key:" + key+"]");
                            cacheMap.remove(key);
                        }
                    }
                }
                try {
                    Thread.sleep(CHECK_TIMEOUT);
                } catch (Exception e) {
                    logger.error("[CacheMap Error]", e);
                }
            }
        }
    }

    public Object get(String key) {
        CacheEntry<String, Object> entry = cacheMap.get(key);
        return entry == null ? null : entry.value;
    }

    public Object put(String key, Object value) {
        CacheEntry<String, Object> entry = new CacheEntry<String, Object>(key, value);
        synchronized (cacheMap) {
            cacheMap.put(key, entry);
        }
        return value;
    }

    public boolean containsKey(String key) {
        return cacheMap.containsKey(key);
    }

    public Object remove(String key) {
        return cacheMap.remove(key);
    }

}
